package com.efrei.uchat.io;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

import org.apache.log4j.Logger;

import com.efrei.uchat.message.Message;
import com.efrei.uchat.model.user.Chatter;
import com.efrei.uchat.server.ClientListener;
import com.efrei.uchat.server.UChatServer;

public class Session {
	
	private static Logger logger = Logger.getLogger(Session.class);
	
	private int id;
	private Chatter chatter;
	private Socket client;
	private UChatServer server;
	
	private ClientListener listener;
	
	public Session(int id, UChatServer server, Socket client) throws IOException {
		this.id = id;
		this.server = server;
		this.client = client;
		
		// start listener with server as observer
		listener = new ClientListener(this);
		listener.addObserver(server);
		new Thread(listener).start();
	}
	
	/**
	 * asynchronously send message to session's user
	 * @param message
	 */
	public void send(final Message message) {
		new Thread(new Runnable() {
			
			private PrintWriter out;
			
			@Override
			public void run() {
				try {
					out = new PrintWriter(client.getOutputStream());
					out.println(message.toString());
					out.flush();
				} catch(IOException e) {
					e.printStackTrace();
					try {
						logger.error("Error while sending message to "+
								chatter+". Connection closed");
						disconnect();
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
				}
			}
		}).start();
	}
	
	public int getId() {
		return id;
	}
	
	public Chatter getChatter() {
		return chatter;
	}
	
	public Socket getClient() {
		return client;
	}
	
	public UChatServer getServer() {
		return server;
	}
	
	public ClientListener getListener() {
		return listener;
	}

	public void setChatter(Chatter chatter) {
		this.chatter = chatter;
	}

	public void disconnect() throws InterruptedException {
		System.out.println("disconnected "+this);
		server.sessionDisconnected(this);
		
		try {
			client.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}
